#ifndef __UTILITY_H_
#define __UTILITY_H_
#include <stdint.h>
#include "stdbool.h"

#define UTIL_MIN(a, b)	((a) < (b) ? (a) : (b))
#define UTIL_MAX(a, b)	((a) < (b) ? (b) : (a))
#define MIN_VALUE(n1,n2)	(((n1) < (n2)) ? (n1) : (n2))
#define BV(x)												(1<<(x))
#define SWAP16(x)										((x>>8) | (x<<8))
#define SWAP32(x)										(((x>>24)&0x000000FF) | ((x>>8)&0x0000FF00) | \
								 										((x<<8)&0x00FF0000)  | ((x<<24)&0xFF000000))
#define IP_ADDR(a1,a2,a3,a4)				(((uint32_t)a4)<<24) | (((uint32_t)a3)<<16) | \
																		(((uint32_t)a2)<< 8) | (((uint32_t)a1)<< 0)


#define StrToVal_Dec(str, val)	StrToVal(str, 10, val)
#define StrToVal_Hex(str, val)	StrToVal(str, 16, val)

#define StrToArray_Dec(str, slen, arr, size)	\
	StrToArray(10, str, slen, arr, size)
#define StrToArray_Hex(str, slen, arr, size)	\
	StrToArray(16, str, slen, arr, size)

uint8_t ValueToHexCode(uint8_t val);
uint8_t ValueToDecCode(uint8_t val);
const char* StrToVal(const char* str, uint8_t base, uint64_t* val);
uint8_t CharToValue(uint8_t ch, uint8_t base);

unsigned char U8ToHex(char *digit, unsigned char len);
unsigned long U32ToHex(char *digit, unsigned char len);
unsigned long U32ToData(char *digit, unsigned char len);
unsigned char U8ToData(char* digit, unsigned char len);
//unsigned char CountSetBits(unsigned char nibble);
//uint8_t Buffer_Xor(uint8_t buf[], uint32_t len);
//uint16_t Odd(uint8_t data, uint8_t data_bits);
//void BitBuffer_Put(uint8_t bit_buffer[], uint32_t position, uint8_t val);
//uint8_t BitBuffer_Get(uint8_t bit_buffer[], uint32_t bit_num);
uint64_t BufToValue(uint8_t lsb, uint8_t buf[], uint8_t len);
void DecStrToValue(uint8_t* strDec, uint8_t strLen, uint64_t* value);
//	int HexStrToBuf(uint8_t* strHex, uint32_t strLen, uint8_t* buf, uint32_t bufSize);
int StrToArray(uint8_t base, const uint8_t* str, uint16_t slen, uint8_t* buf, uint16_t size);

void Mem_Reverse(uint8_t* buffer, int length);
void Mem_Reverse_Copy(uint8_t *to, const uint8_t *from, int length);
int Mem_Backward_Copy(uint8_t *to, int tsize, uint8_t *from, int length, int count);


//consecutive zero bits
//find the number of trailing zeros in v
int Bit_ConsecutiveZeroBits(unsigned int v);
int BitBuffer_ConsecutiveZeroBits(uint8_t bit_buffer[], uint32_t byte_count);

int StrNLen(const char* string, int maxLength);

int hexDataToStrData(char *str, uint32_t strLen, uint8_t *hex, uint32_t hexLen, bool type);
int strDataToHexData (uint8_t *hex, char *str);
uint16_t swap16(uint16_t value);
uint32_t swap32(uint32_t value);
void des3_enc(uint8_t * plain, uint8_t * cipher, uint32_t len, const uint8_t keys[16]);
void des3_dec(uint8_t * cipher, uint8_t * plain, uint32_t len, const uint8_t keys[16]);
void des_dec(uint8_t * cipher, uint8_t * plain, uint32_t len, const uint8_t keys[8]);
#endif
